package demo01Array;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User:咭咭熊
 * Date:2021 - 09 - 07
 * Time:11:33
 */

import java.util.Arrays;

/***
 * 二、数组
 * 1..数组：一块连续的内存，存储的是相同数据类型的集合；
 * 数组——数组对象；对象——存放在堆中；
 * JVM软件： 由 C/C++实现的；
 * 包含五个部分：JVM栈、本地方能发展、堆、方法区、程序计数器
 *
 * 2.引用一定发生在栈上面吗？——需要判断当前引用是局部变量还是成员变量
 * 不一定，当为局部变量的时候，引用才发生在栈上面
 *
 * 3.打印数组的三种方式
 * （1）for循环
 * （2）foreach
 *  (3)Arrays.toString()
 * for循环 和 foreach 的区别
 * for——可以使用下标的
 * foreach——没有下标的
 *
 * 4.使用数组时的常见问题：
 * （1）数组越界访问——java.lang.ArrayIndexOutOfBoundsException
 * （2）空指针异常（检查哪个引用是null）——java.lang.NullPointerException
 *
 * 5.null 在java中表示“空引用”，也就是一个无效的引用
 *
 * 6.JVM内存区域划分
 * （1）JVM虚拟机栈
 * （2）本地方法栈——运行C/C++代码
 * （3）堆——存储对象
 * （4）方法区（包含运行时常量池）——静态成员变量
 * （5）程序计数器——保存下一条指令的地址
 *  JDK1.7之后，运行时常量池在堆中；
 *
 * 对于线程的私有区域：程序计数器、JVM虚拟机栈、本地方法栈
 * 对于线程的共享区域：堆、方法区
 *
 * 局部变量和引用保存在栈上，new出来的对象保存在堆上年；
 * 堆的空间比较大，栈的空间比较小；
 * 堆是整个JVM共享一个；而栈每个线程都有一份（一个Java程序中可能存在多个栈）
 *
 * 7.实现toString()方法
 *
 */
public class Arr {
    /***
     * 实现toString()
     * @param array
     */
    public static String  myToString(int[] array){
        if(array == null){
            return null;
        }
        String ret = "[";
        for (int i = 0; i < array.length ; i++) {
            ret = ret + array[i];
            if(i != array.length - 1){
//                ret = ret  + array[i] + ", ";
                ret += ", ";
            }
        }
        ret += "]";
        return ret;
    }

    public static void main9(String[] args) {
        int[] array = {1,2,3,4,5};
        System.out.println(Arrays.toString(array));
        System.out.println(myToString(array));
        System.out.println(myToString(null));
    }
    /***
     * 将原来的数组中的内容扩大为原来的2倍——不修改原来的数组
     * @param arr2
     * @return
     */
    public static int[] func2(int[] arr2){
        int[] ret = new int[arr2.length];
        for (int i = 0; i < arr2.length; i++) {
            ret[i] = arr2[i] * 2;
        }
        return  ret;
    }
    /***
     * 将原来的数组中的内容扩大2倍——改变了原来的数组
     * @param arr2
     * @return
     */
    public static int[] func1(int[] arr2){
        for (int i = 0; i < arr2.length; i++) {
            arr2[i] = arr2[i] * 2;
        }
        return arr2;
    }
    public static void main8(String[] args) {
        int[] arr1 = {1,2,3};
        int[] ret = func1(arr1);
        System.out.println(Arrays.toString(ret));
        System.out.println(arr1);
    }
    public static void main7(String[] args) {
        int[] arr = {1,2,3};
        func(arr);
        System.out.println("arr[0] = " + arr[0]);
    }
    public static void func(int[] a){
        a[0] = 10;
        System.out.println("a[0] = " + a[0]);
    }
    public static void main6(String[] args) {
        int[] arr1 = {1,2,3};
        int[] arr2 = new int[]{1,2,3};
        //arr这个引用指向了arr2这个引用所引用的对象
        arr1 = arr2;
    }
    public static void main5(String[] args) {
        int[] array = {1,2,3};
        array = new int[]{1,4,5,7,6};

    }
    /***
     * 4.数组交换值
     * 一个对象可以被多个引用所引用
     * 一个引用只能同时引用一个对象
     */
    public static void swap(int[] arr){
        int tmp = arr[0];
        arr[0] = arr[1];
        arr[1] = tmp;
    }
    public static void main4(String[] args) {
        int[] array = {10,30};
        System.out.println(array[0] + " " +  array[1]);
        swap(array);
        System.out.println(array[0] + " " + array[1]);
    }
    /***
     * 3.数组常见的问题：
     * （1）数组下标越界访问；
     * （2）空指针异常
     * @param args
     */
    public static void main3(String[] args) {
        int[] array1 = {1,2,3,4,5};
        System.out.println(array1[4]);

        //代表此引用不指向任何对象
        int[] array2 = null;
        System.out.println(array2.length);//报空指针异常
    }
    //2.打印数组的方式 —— 3种
    public static void main2(String[] args) {
        int[] array1 = {1,2,3,4,5};
        //(1)for循环
        for (int i = 0; i < array1.length; i++) {
            System.out.print(array1[i] + " ");
        }
        System.out.println();
        //(2)foreach
        for(int x: array1){
            System.out.print(x + " ");
        }
        System.out.println();

        //(3)使用操作数组的工具类:Arrays.toString()——将数组以字符串的形式进行输出
    /*    String ret = Arrays.toString(array1);
        System.out.println(ret);*/

        System.out.println(Arrays.toString(array1));
    }

//    int a = 10;//实例成员变量——存放于堆上的
//    static int b = 20;//静态成员变量——存放于方法区
//    int[] aray4 = {1,2,3,4,5};
    public static void main1(String[] args) {
        /***
         * array1、array2、array3:属于引用变量，主要用于存放地址
         */
        //（1）定义且初始化一个数组——静态初始化
        int[] array = {1,2,3,4,5};//array1引用一个堆上的对象
        //(2)定义了一个数组，但是没有进行初始化（默认值为0）；new关键字
        int[] array2 = new int[10];
        //(3)动态初始化数组
        int[] array3 = new int[]{1,2,3,4,5};

    }
}
